package com.commons.sql;

import java.util.LinkedList;

/**
 * 根据sql语句生成其相应的count语句
 * 例如：
 * select * from user where name=linjia 
 * 变成
 * select count(*) from user where name=linjia
 * @author linjia
 *
 */
public class SqlCountUtil {
	
	private final static String  SELECT = "select";
	private final static String  FROM = "from";
	private final static int MAXNUM = 100000;
	
	
	/**
	 * 
	 * 方法说明：根据相应的SQL语句自动产生它的计算行数SQL语句
	 * 创建日期：2009-2-23,下午02:25:16,hyc
	 * @return
	 */
	public static String getCountSql(String sql){
		sql = sql.replaceAll("(^\\s*\\()|(\\)\\s*$)", "")
				 .replaceAll("(?i)select\\s+", "select ")
				 .replaceAll("(?i)from\\s+", "from ")
				 .replaceAll("(?i)order\\s+by", "order by")
				 .replaceAll("(?i)limit", "limit");
		int pointer = sql.indexOf(SELECT, 0);
		//简单语法分析栈
		LinkedList<String> stack  =  new LinkedList<String>();
		stack.push(SELECT);
		while(!stack.isEmpty()){
			String first = stack.getFirst();
			int p1 = sql.indexOf(SELECT, pointer + 4);
			int p2 = sql.indexOf(FROM, pointer + 4);
			p1 = (p1 == -1)? MAXNUM: p1;
			p2 = (p2 == -1)? MAXNUM: p2;
			if(p1 == MAXNUM && p2 == MAXNUM) throw new RuntimeException("SQL语句非法...");
			if(p1 <= p2){
				pointer = p1;
				if(first.equals(SELECT))stack.push(SELECT);
				else stack.pop();
			}else{
				pointer = p2;
				if(first.equals(FROM))stack.push(FROM);
				else stack.pop();
			}
		}		
		int fromIndex = pointer;
		sql = sql.substring(fromIndex);
		int orderIndex = sql.lastIndexOf("order by");
		if(orderIndex != -1 && sql.indexOf(")", orderIndex) < 0){
			sql = sql.substring(0, orderIndex);
		}
		int limitIndex = sql.lastIndexOf("limit");
		if(limitIndex != -1 && sql.indexOf(")", limitIndex) < 0){
			sql = sql.substring(0, limitIndex);
		}
		return "select count('A') c " + sql;
	}
}
